﻿using System;
using System.Linq;
using Cool.Core.Entities;
using Cool.Core.Managers;
using Furion;
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Cool.EntityFramework.Core
{
    [AppDbContext("Cool", DbProvider.MySql)]
    public class DefaultDbContext : AppDbContext<DefaultDbContext>, IMultiTenantOnTable, IModelBuilderFilter
    {
        public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
        {
        }
        public object GetTenantId()
        {
            return base.Tenant?.TenantId ?? Guid.Empty;
        }


        public void OnCreated(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator)
        {

        }

        /// <summary>
        /// 配置假删除过滤器
        /// </summary>
        /// <param name="modelBuilder"></param>
        /// <param name="entityBuilder"></param>
        /// <param name="dbContext"></param>
        /// <param name="dbContextLocator"></param>
        public void OnCreating(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator)
        {
            var expression = base.FakeDeleteQueryFilterExpression(entityBuilder, dbContext);
            if (expression == null) return;

            entityBuilder.HasQueryFilter(expression);
        }

        protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result)
        {
            // 获取当前事件对应上下文
            var dbContext = eventData.Context;

            // 获取所有新增和更新的实体
            var entities = dbContext.ChangeTracker.Entries().Where(u => u.State == EntityState.Added || u.State == EntityState.Modified);

            var entityEntries = entities.ToList();
            if (!entityEntries.Any()) return;
            var userManager = App.GetService<IUserManager>();
            var userId = userManager.UserId;

            foreach (var entity in entityEntries)
            {
                if (entity.Entity.GetType().IsSubclassOf(typeof(DEntityBase)))
                {
                    var dEntityBase = entity.Entity as DEntityBase;
                    switch (entity.State)
                    {
                        // 自动设置租户Id
                        case EntityState.Added:
                            entity.Property(nameof(Entity.TenantId)).CurrentValue = GetTenantId();
                            dEntityBase.CreatedTime = DateTimeOffset.Now.LocalDateTime;
                            dEntityBase.CreatedBy = userId;
                            break;
                        // 排除租户Id
                        case EntityState.Modified:
                            entity.Property(nameof(Entity.TenantId)).IsModified = false;
                            dEntityBase.UpdatedTime = DateTimeOffset.Now.LocalDateTime;
                            dEntityBase.UpdatedBy = userId;
                            break;
                    }
                }
                else
                {
                    switch (entity.State)
                    {
                        // 自动设置租户Id
                        case EntityState.Added:
                            entity.Property(nameof(Entity.TenantId)).CurrentValue = GetTenantId();
                            break;
                        // 排除租户Id
                        case EntityState.Modified:
                            entity.Property(nameof(Entity.TenantId)).IsModified = false;
                            break;
                    }
                }
            }
        }
    }
}